查看原文
其他

跨平台通杀看不懂?老师傅带你读懂网络协议漏洞

蛤士奇 微步在线研究响应中心 2022-05-24

1

为什么单列一类漏洞?

一般而言,我们对漏洞有三种传统分类:Web漏洞、二进制漏洞、逻辑漏洞

这样的分类方式是来自于技术类别。Web漏洞就是指在基于Web技术的软件中由于设计或实现不当导致的漏洞,例如我们常见的XSS、SQLi、XXE等,都是Web技术上的漏洞;二进制漏洞是指软件在对内存的管理、使用、解析的过程中由于不当的设计或实现导致的漏洞,例如OOB、UAF等;而逻辑漏洞是指程序逻辑的问题导致的漏洞,一般来说不属于前面两类的漏洞多数情况下都会被理解为是逻辑漏洞。
而我们单独提“协议漏洞”这个概念的时候是按业务场景来分类的,其实不止是协议漏洞,在实际中还有很多漏洞都不能按上述的三种类别来准确描述其特点,例如环境变量注入漏洞、各类利用RPC实现提权的漏洞等。就拿RPC提权来说,当你和别人交流时首先介绍这是一个“逻辑漏洞”的话大概率人家会极为疑惑,但是如果你说这是一个“RPC提权漏洞”的话人家就能马上有个大致概念了,也更符合一般的交流习惯。

而把“协议漏洞”单列一类基本上有如下的原因:

  • 大部分都是协议设计阶段引入的问题,而不是软件实现阶段;

  • 大部分存在跨软件、跨操作系统,甚至是跨硬件平台的通杀现象;

  • 漏洞利用的目标通常是实现通信劫持,而不是RCE/ACE;

“协议漏洞”在漏洞响应处置上和一般软件漏洞不同,因为常常出现跨软件通杀,所以一个漏洞的修复就可能需要协调多个厂商共同完成;另外如果是协议设计上的问题,那么下游软件开发者可能无法拿出一个合理的修复方案,最终需要协议设计者的参与。
2

来看几个拒绝服务的 case

说了那么多“虚”的东西,现在来看点“实”的例子。从拒绝服务开始,首先给大家介绍的是一类叫 CPDoS(Cache Poisoning Denial of Service)的漏洞。这是 Web 缓存投毒的一种:CPDoS通常出现在通过反向代理给Web server提供静态资源 cache 服务的场景中,也就是 CDN。CDN 的 cache 可以理解成一个key-value 索引,多数情况下这个 key 就是 HTTP 请求中的 URL + Host + 一些关键 header,这里不会把所有header都纳入key,原因就是有些header会随着时间或者用户而变化(例如cookie),如果将其纳入key那么会把一份静态资源 cache 多次,产生浪费。而在这种场景下如果对HTTP请求中key以外的部分后端 web server 和 cache server 有不同的解析方式的话,就有可能出现 CPDoS 问题。

CPDoS case 1

当 Client 向 Server 发送的 HTTP 请求中包含一个长度超过 Server 接受范围的header,那么Server一般会返回一个400错误的响应。这在一般的Web Server场景下没什么问题,但如果 Client 和 Web Server 中间插了一个Cache Server(CDN节点)的时候就可能出现 Cache Server 和 Web Server 对 header 长度的限制不同的问题。此时如果 Cache Server 对header 长度的限制大于 Web Server 的限制,那么 Client 发过来的 HTTP 请求就能穿越 Cache Server 顺利到达 Web Server,然后得到一个大大的400错误,并且被 Cache Server  缓存下来。

如果此时 Client 请求的是 /index.html,Host 为 example.org,Cache key为 URL+Host,那刚刚 Client 的请求所产生的400 Cache 就会影响到其他同样访问 example.org/index.com 的用户,由此实现一例 DoS 攻击。

当然 CPDoS 的攻击手法还可以有各种变体: 

CPDoS case 2

一部分的 Web Server 支持一种叫做 “HTTP Method Override” 的技术,也就是用一个 header 来覆盖掉 HTTP 请求中的 Method,最常见的就是“X-HTTP-Method-Override” header,当 Client 发送一个 GET 请求并带上X-HTTP-Method-Override = POST 时,这个请求实际会被 Web Server 或者Web 中间件当作 POST 请求处理。

这种情况下 Client 发出一个 example.org/index.html 的 GET 请求,并override 成 POST,如果 Web Server 那里没有这个路径下 POST 请求的handler,那就会产生一个404错误,当 Cache Server 缓存下这个404错误后,和上文同样的问题也会影响所有访问 example.org/index.html 的用户,于是你又搞成了一次 DoS 攻击。

......,这里省略了一些细节,更全面的内容可以参考以下链接:https://cpdos.org/

从 CPDoS 的例子里面大家可以发现,单独把 Cache Server 或者 Web Server 拆出来看都没有问题,但是当他们放在一起使用的时候就会出现问题。对,就是这么奇怪!而且这种问题还会因为 Cache Server 和Web Server 对 HTTP 协议解析细节的各种不同而产生细分变体,再加上多级缓存结构和 Web 应用所形成的协议特点最终让 CPDoS 在实际环境下变得五花八门。

而这时你应该会意识到:

(1)CPDoS 不是某个具体软件的问题,而是软件组合使用+不恰当的 Cache 策略导致的;

(2)修复 CPDoS 大概率不是软件开发层面的事情,而是运维层面的事情。

3

看完拒绝服务再来瞧瞧通信劫持
接下来要说的是 HTTP Request Smuggling,这种漏洞在国内的知名度要比上文中的 CPDoS 大一些。HTTP Request Smuggling 的技术原理如下:
首先 HTTP 是基于 TCP 的,最原始的情况下一个 HTTP Session 的生命周期是等于一个 TCP Session 的生命周期的,但是频繁拆建 TCP 连接是一个比较消耗资源的事情,尤其对于 Client 和 Server 之间需要一批多次发送数据的场景。于是就有了 HTTP 协议的一个著名的 header:“Connectoin: Keep-Alive”,这个 header 的作用是通知对方当前这个 HTTP Session 结束后不要忙关 TCP 连接,后面还要用它!也就是用一个 TCP Session 去承载多个 HTTP Session。而为了进一步优化通信性能,还在此基础上发展出了 Pipeline 方式,也就是当一个 HTTP 请求发出后不用等待响应就直接发送下一个 HTTP 请求,可以看到这对于提高通信吞吐效率来说非常有效。

其实这里就引入了新的问题:HTTP 是一个以“报文”为基本传输单位的协议,但 TCP 是一个以“流”为基本传输单位的协议;这两者并不是天然兼容的,要在一个“流”上面准确的传输多个“报文”需要额外的分割策略。所谓“分割策略”最简单的例子就是分隔符(例如连续两个”\r\n”就可以用来分割 HTTP header 和body)。HTTP 上最基本的两种“分割策略”是:

(1) Content-Length

(2) Transfer-Encoding=chunked

第一种就是在 HTTP header 中使用一个 Content-Length 来指定当前报文的长度,超出这个长度的数据就属于下一个报文。第二种则是按照一种特殊的编码方式组织数据,例如这样:

POST /test.action HTTP/1.1\r\nHost: example.org\r\nContent_type: text/plain\r\nTransfer-Encoding: chunked\r\n\r\n\r\n4\r\nTest\r\n5\r\nPages\r\n0\r\n\r\n

其中的 4\r\n,Test\r\n,就是一个 chunk,数字4代表后面跟了4个字节,而 \r\n 是分隔符。当 Client 发送的 HTTP 请求里面同时包含这两种分割策略时不同的 Server 可能对这个请求会有不同的理解,例如下面这样:

GET / HTTP/1.1\r\nHost:localhost\r\nContent-length:56\r\nTransfer-Encoding: chunked\r\nDummy:Header\r\n\r\n0\r\n\r\nGET /tmp HTTP/1.1\r\nHost:localhost\r\nDummy:Header\r\n\r\nGET /tests HTTP/1.1\r\nHost:localhost\r\nDummy:Header\r\n\r\n

如果 Server 对 Content-length 的解析优先于 Transfer-Encoding 的话,这段数据会被理解为三个 HTTP 请求,但如果反过来的话则只会被理解为两个 HTTP 请求。和上文中的 CPDoS 类似,在 CDN 的场景下,如果前后两个Server 对 HTTP 协议的理解不同的话就会出现问题。例如在第三方用户的请求里面插入一段攻击者指定的数据:

细节参考链接:https://xz.aliyun.com/t/6878

HTTP Request Smuggling 和 CPDoS 有很多相似之处:

(1)都存在跨软件的广泛影响;

(2)都很难通过软件开发者的漏洞修补去解决问题。

但 HTTP Request Smuggling 带来的威胁要比 CPDoS 更上一个台阶,它可以用来劫持(篡改)正常用户的通信内容。
4

最后来个更绝的:看我如何突破防火墙
除了拒绝服务和通信劫持以外还有一类更特殊的case:“自外向内突破防火墙”,这个就是2020年末的时候被披露的 NAT Split Streaming 漏洞。这个漏洞的技术细节大致如下:
一般我们使用的家用路由器或者防火墙大多是NAT网关,NAT网关的作用是让多个设备共享同一个IP地址来接入互联网,一般来说NAT网关需要维护一个内外网的地址映射表来实现地址与端口的转换。

这张图里面就是一个单方向 NAT(SNAT)的地址映射,内网发往外网的IP报文的源地址与源端口会被 NAT 网关篡改,变成 NAT 网关自己对外的 IP 和端口,而此时就需要维护一个内网 IP+端口到外网 IP+端口的映射表。当外网的数据回来时就可以按这张映射表来把 IP 包的目的地址和目的端口再改回来。

这种单方向的 NAT 有个特点,就是外网无法主动向内网 IP 发送数据,所以很多防火墙也是这种结构。
刚刚说的 NAT 的技术实际上无法满足一些特殊协议的工作需求,例如 FTP。

FTP 在主动模式下需要 Client 和 Server 都主动连接对方,只能单向通行的 SNAT 就无法 cover 这种需求了,所以又有了一个叫 ALG(Application Level Gateway)的技术:

说白了 ALG 干的事情就是又去篡改应用层的网络数据,把 FTP 的 PORT 报文里面的 IP 和端口再篡改一次,并且在 NAT 的映射表里头把篡改的这个 IP 给他添加进去,例如这个图里头把 PORT 报文里头的192.168.1.2:1084改成 NAT 网关的公网 IP+端口,再把这个公网IP和端口映射回内网的机器上。
刚刚说的是 FTP 协议的 ALG,很多其他协议也都有 ALG 支持。
这里的 NAT Split Streaming 漏洞就是 ALG 的一种缺陷:攻击者利用 TCP 的分段机制去伪造一个可以触发 ALG 工作的数据包,然后利用 ALG 把内网的 IP+端口映射到外网,从而实现从外网突破 NAT 直接访问内网主机。这里攻击者使用的是 SIP 协议的 REGISTER 包,它大概长这样:
REGISTER sip:192.168.2.89 SIP/2.0Via: SIP/2.0/UDP 192.168.2.161:10586Max-Forwards: 70From: <sip:01062237496@192.168.2.89>;tag=ca04c1391af3429491f2c4dfbe5e1b2e;epid=4f2e395931To: <sip:01062237496@192.168.2.89>Call-ID: da56b0fab5c54398b16c0d9f9c0ffcf2@192.168.2.161CSeq: 1 REGISTERContact: <sip:192.168.2.161:10586>;methods="INVITE, MESSAGE, INFO, SUBSCRIBE, OPTIONS, BYE, CANCEL, NOTIFY, ACK, REFER"User-Agent: RTC/1.2.4949 (BOL SIP Phone 1005)Event: registrationAllow-Events: presenceContent-Length: 0
里面的 Contact 字段就是 ALG 会去处理的字段,如果内网主机向外发送这么一个 SIP 包,那么 Contact 字段里面的 IP+端口就会被ALG映射出去。要发起攻击,可以给内网的用户发送一个钓鱼链接,受害者点开后会通过浏览器发送一个超长的 POST 数据,而只需要控制这个 POST 数据的长度和内容就能在TCP数据的第二或者第三分段上创造出一个长得和 SIP REGISTER 包一模一样的数据包,就像这样:
控制分段长度的技术细节略微复杂,涉及到 TCP 握手中的 MSS 和 IP 协议的 MTU,更多细节参考以下链接:https://forum.butian.net/share/88

这个漏洞的特殊之处在于:

(1)它不是程序实现上的失误导致的,而是 ALG 这种 NAT 上补充出来的技术在设计上就存在缺陷;

(2)这带来的一个很棘手的现实状况:没有完美的修补方案。要么完全不用 ALG,要么只能通过限制 ALG 的功能来缓解问题;

(3)NAT Split Streaming 也是一个跨软件甚至跨硬件的漏洞,从各个厂牌的家用路由器到商用防火墙均有中招的例子。

5

总结
上面列举了三个大 case 来介绍网络协议漏洞,总的来说就是这是一个大多数没有 CVE 编号,但实际影响却又不小的漏洞类别。虽然几乎不能达到 RCE/ACE 的利用效果,却由于广泛的影响和自身的技术特点带来了响应处置上的独特挑战。业界对此类漏洞的关注度目前还不是特别高,但应对这些“特殊”漏洞的挑战还是值得从业人员们调整一下思路,新的风暴永远都在出现。

公众号内回复“协议”,可获取PDF版报告

- END -

微步情报局招聘通道


安全服务工程师  戳我查看岗位详情

安全分析师(威胁追踪方向)戳我查看岗位详情

安全分析师(主机检测方向-Java)戳我查看岗位详情

点击下方名片,关注我们

第一时间为您推送最新威胁

阅读原文,可加入粉丝群~

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存